#include "SimpleChat.h"

void  SimpleChat::RunService()
{
	peer = new Peer();
	std::cout << "s for Sever or c for Client " << std::endl;
	char userTyp = '-';
	bool choice = false;
	while (!choice)
	{
		cin >> userTyp;

		if (userTyp == 's' || userTyp == 'c')
		{
			choice = true;
		}
	}

	SocketDescriptor sd;

	if (userTyp == 'c')
	{
		//client code 
		//peer->peerData->Startup(1, &sd, 1);
		//peer->SetIsServer(false);
		RunClientCode();
	}
	else
	{

		//server code
		sd = SocketDescriptor(SERVER_PORT, 0);
		//peer->peerData->Startup(MAX_CLIENTS, &sd, 1);
		//peer->SetIsServer(true);
		RunServerCode();
	}
	cout << "" << endl;
}

SimpleChat::SimpleChat()
{
	RunService();
}

void SimpleChat::RunServerCode()
{
	cout << "Running as a server" << endl;
	//peer->peerData->SetMaximumIncomingConnections(MAX_CLIENTS);

	Packet *packet;

	while (1)
	{
		//recieve data 
		for (packet = peer->peerData->Receive(); packet; peer->peerData->DeallocatePacket(packet), packet = peer->peerData->Receive())
		{
			switch (packet->data[0])
			{
			case ID_REMOTE_DISCONNECTION_NOTIFICATION:
				printf("Server: Another client has disconnected.\n");
				break;
			case ID_REMOTE_CONNECTION_LOST:
				printf("Server: Another client has lost the connection.\n");
				break;
			case ID_REMOTE_NEW_INCOMING_CONNECTION:
				printf("Server: Another client has connected.\n");
				break;
			case ID_CONNECTION_REQUEST_ACCEPTED:
				
				printf("Server: Our connection request has been accepted. and hellow world message sent to %s\n",packet->systemAddress);
				break;
			case ID_NEW_INCOMING_CONNECTION:
				printf("Server: A connection is incoming.\n");
				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				printf("Server: The server is full.\n");
				break;
			case ID_GAME_MESSAGE_1:
				{
					RakString rs;
					BitStream bsIn(packet->data, packet->length, false);
					bsIn.IgnoreBytes(sizeof(RakNet::MessageID));
					bsIn.Read(rs);
					printf("%s \n", rs.C_String());
				}
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				printf("Server: A client has disconnected.\n");
				break;
			case ID_CONNECTION_LOST:
				printf("Server: A client lost the connection.\n");
				break;
			default:
				printf("Server: Message with identifier %i has arrived.\n", packet->data[0]);
				break;
			}
		}
	}
}

void SimpleChat::RunClientCode()
{
	string input = "";
	string emptyString = "";
	Packet *packet;


	cout << "Running as a client" << endl;
	cout << "Please enter ip addres sof the server" << endl;

	cin >> input;

	if (strcmp(input.c_str(), ""))
	{
		input = "127.0.0.1";
	}

	cout << "" << endl;
	peer->peerData->Connect(input.c_str(),SERVER_PORT, 0, 0);

	while (1)
	{
		for (packet = peer->peerData->Receive(); packet; peer->peerData->DeallocatePacket(packet), packet=peer->peerData->Receive())
		{
			switch (packet->data[0])
			{
			case ID_REMOTE_DISCONNECTION_NOTIFICATION:
				printf("Another client has disconnected.\n");
				break;
			case ID_REMOTE_CONNECTION_LOST:
				printf("Another client has lost the connection.\n");
				break;
			case ID_REMOTE_NEW_INCOMING_CONNECTION:
				printf("Another client has connected.\n");
				break;
			case ID_CONNECTION_REQUEST_ACCEPTED:
				{
					printf("Our connection request has been accepted");
					// Use a BitStream to write a custom user message
					// Bitstreams are easier to use than sending casted structures, and handle endian swapping automatically
					RakNet::BitStream bitSream;
					bitSream.Write((RakNet::MessageID)ID_GAME_MESSAGE_1);
					bitSream.Write("Hello World");
					peer->peerData->Send(&bitSream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
				}
				printf("Our connection request has been accepted.\n");
				break;
			case ID_NEW_INCOMING_CONNECTION:
				printf("A connection is incoming.\n");
				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				printf("The server is full.\n");
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				printf("We have been disconnected.\n");
				break;
			case ID_CONNECTION_LOST:
				printf("Connection lost.\n");
				break;
			default:
				printf("Message with identifier %i has arrived.\n", packet->data[0]);
				break;
			}
		}
	}

}

SimpleChat::~SimpleChat()
{
	delete peer;
}

